package com.heima.admin.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.heima.admin.feign.ArticleFeign;
import com.heima.admin.feign.WemediaFeign;
import com.heima.admin.mapper.AdChannerMapper;
import com.heima.admin.mapper.AdSensitiveMapper;
import com.heima.admin.service.WemediaNewsAutoScanService;
import com.heima.common.aliyun.GreenImageScan;
import com.heima.common.aliyun.GreenTextScan;
import com.heima.common.fastdfs.FastDFSClient;
import com.heima.gateway.utils.common.SensitiveWordUtil;
import com.heima.model.admin.pojos.AdChannel;
import com.heima.model.article.pojos.ApArticle;
import com.heima.model.article.pojos.ApArticleConfig;
import com.heima.model.article.pojos.ApArticleContent;
import com.heima.model.article.pojos.ApAuthor;
import com.heima.model.wemedia.pojos.WmNews;
import com.heima.model.wemedia.pojos.WmUser;
import io.seata.spring.annotation.GlobalTransactional;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.*;

/**
 * Created with IntelliJ IDEA.
 *
 * @Auther: 王可
 * @Date: 2021/02/01/20:31
 * @Description:
 */
@Service
public class WemediaNewsAutoScanServiceImpl implements WemediaNewsAutoScanService {

    @Resource
    private WemediaFeign wemediaFeign;

    @Resource
    private ArticleFeign articleFeign;

    @Resource
    private AdChannerMapper adChannerMapper;

    @Resource
    private GreenTextScan greenTextScan;

    @Resource
    private GreenImageScan greenImageScan;

    @Value("${fdfs.web-server-url}")
    String fdfsUrl;

    @Resource
    private FastDFSClient fastDFSClient;

    @Resource
    private AdSensitiveMapper adSensitiveMapper;

    @GlobalTransactional
    @Override
    public void autoScanByMediaNewsId(Integer id) {
        //1.检查参数
        if (id == null) {
            return;
        }
        //2.根据远程调用自媒体自媒体信息
        WmNews wmNews = wemediaFeign.findById(id);
        if (wmNews == null) {
            return;
        }

        //3.如果文章状态为8或者4，并且发布时间小于等于当前时间，发布文章
        if ((wmNews.getStatus() == 8 || wmNews.getStatus() == 4) &&
                wmNews.getPublishTime().getTime() <= System.currentTimeMillis()) {
            saveAppArticle(wmNews);
            return;
        }

        //4.如果文章状态为1代表状态为待审核，需对文章文本和图片进行自动审核
        if (wmNews.getStatus() == 1) {
            //4.1抽取
            Map<String, Object> map = handleTextAndImages(wmNews);

            //4.2取出文本信息进行阿里云文本审核
            String text = (String) map.get("text");
            if (text != null) {
                boolean flagText = handleTextScan(wmNews, text);
                if (!flagText) {
                    return;
                }
            }

            //4.3取出图片信息进行阿里云图片审核
//            String image = (String) map.get("image");
            List<String> imagesList = (List<String>) map.get("image");
//            ArrayList<String> imagesList = new ArrayList<>();
//            imagesList.add(image);
//            List<String> imagesList = (List<String>) map.get("image");
                boolean flagInames = handleImagesScan(wmNews, imagesList);
                if (!flagInames) {
                    return;
            }

            //4.4DFA自管理敏感词审核
            if (StringUtils.isNotBlank(text)) {
                //对敏感词进行过滤查询
                boolean sensitiveFlag = handleSensitive(wmNews, text);
                if (!sensitiveFlag) {
                    return;
                }
            }

            //审核通过，判断发布时间是否小于等于当前时间，小于等于当前时间就发布，否则改为等待发布
            if (wmNews.getPublishTime() != null && wmNews.getPublishTime().getTime() <= System.currentTimeMillis()) {
                //发布文章
                saveAppArticle(wmNews);
            } else {
                //审核通过，状态改为待发布
                updateWenews(wmNews, (short) 8, "审核通过待发布");
                return;
            }
        }
    }

    private boolean handleSensitive(WmNews wmNews, String text) {
        //查询数据库敏感词集合
        List<String> allSensitive = adSensitiveMapper.findAllSensitive();

        //初始化敏感词库，将查询到的敏感词信息加载到库中
        SensitiveWordUtil.initMap(allSensitive);

        //将数据和词库进行比较查询，看是否含有敏感词汇
        Map<String, Integer> stringIntegerMap = SensitiveWordUtil.matchWords(text);
        if (stringIntegerMap != null && stringIntegerMap.size() > 0) {
            //跟新文章的状态，审核不通过
            updateWenews(wmNews, (short) 2, "文本中包含敏感词，审核失败");
            //说明信息中含有敏感词
            return false;
        }
        //审核通过
        return true;

    }

    private boolean handleImagesScan(WmNews wmNews, List<String> imagesList) {
        //因为阿里云图片审核的是字节数组数据，需要将图片转化为字节数组格式
        ArrayList<byte[]> imageList = new ArrayList<>();

        //遍历集合并处理数据，因为下载图片需要将分组信息和地址信息分开
        for (String images : imagesList) {
            //按照/切割路径，得到分组和地址信息
//            image.replace(fdfsUrl, "").trim();
            String image = images.replace(fdfsUrl, "").trim();
            int index = image.indexOf("/");
            String groupName = image.substring(0, index);
            String imageUrl = image.substring(index + 1);
            try {
                byte[] download = fastDFSClient.download(groupName, imageUrl);
                imageList.add(download);
            } catch (IOException e) {
                e.printStackTrace();
            }

            //开始图片鉴别
            try {
                Map map = greenImageScan.imageScan(imageList);
                //获取审核的意见
                String suggest = (String) map.get("suggestion");
                if ("pass".equals(suggest)) {
                    return true;
                } else if ("review".equals(suggest)) {
                    //待人工审核
                    updateWenews(wmNews, (short) 3, "图片中有不确定因素，需人工审核");
                } else if ("block".equals(suggest)) {
                    updateWenews(wmNews, (short) 2, "图片内容有违规信息，审核失败");
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return false;
    }

    private boolean handleTextScan(WmNews wmNews, String text) {
        try {
            Map map = greenTextScan.greeTextScan(text);
            //获取审核的意见
            String suggest = (String) map.get("suggestion");
            if ("pass".equals(suggest)) {
                return true;
            } else if ("reviev".equals(suggest)) {
                //待人工审核
                updateWenews(wmNews, (short) 3, "文章中有不确定因素，需人工审核");
            } else if ("block".equals(suggest)) {
                updateWenews(wmNews, (short) 2, "文章内容有违规信息，审核失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    private void updateWenews(WmNews wmNews, short status, String msg) {
        wmNews.setStatus(status);
        wmNews.setReason(msg);
        wemediaFeign.updateWmNews(wmNews);
    }

    private Map<String, Object> handleTextAndImages(WmNews wmNews) {
        //获取标题内容
//        StringBuilder textBuilder = new StringBuilder(wmNews.getTitle());
        String title = wmNews.getTitle();
        String textBuilder = ""+title;

        //获取图片集合
        ArrayList<String> imagesList = new ArrayList<>();

        //内容里面既有文本又有图片。所以存到map集合中
        List<Map> maps = JSONArray.parseArray(wmNews.getContent(), Map.class);

        //遍历map集合，取出图片和文本信息
        for (Map map : maps) {
            String type = (String) map.get("type");
            //拼接文本内容
            if ("text".equals(type)) {
                textBuilder=textBuilder+(map.get("value"));
            } else if ("image".equals(type)) {
                imagesList.add(String.valueOf(map.get("value")));
            }
        }

        //添加封面图片
        String images = wmNews.getImages();
        List<String> listImages = Arrays.asList(images.split(","));
        imagesList.addAll(listImages);

        HashMap<String, Object> map = new HashMap<>();
        map.put("text", textBuilder);
        map.put("image", imagesList);
        return map;
    }


    /**
     * 发布方法
     *
     * @param wmNews
     */
    private void saveAppArticle(WmNews wmNews) {
        //保存ap_article信息
        ApArticle apArticle = saveArticle(wmNews);

        //保存ap_article_config信息
        saveArticleConfig(apArticle);

        //保存ap_article_content信息
        saveArticleContent(apArticle,wmNews);


        //修改自媒体状态为9
        wmNews.setArticleId(apArticle.getId());
        updateWenews(wmNews,(short)9,"审核通过");
    }

    private void saveArticleConfig(ApArticle apArticle) {
        ApArticleConfig apArticleConfig = new ApArticleConfig();
        apArticleConfig.setArticleId(apArticle.getId());
        apArticleConfig.setIsForward(true);
        apArticleConfig.setIsDelete(false);
        apArticleConfig.setIsDown(false);
        apArticleConfig.setIsComment(true);
        articleFeign.saveArticleConfig(apArticleConfig);
    }

    private void saveArticleContent(ApArticle apArticle, WmNews wmNews) {
        ApArticleContent apArticleContent = new ApArticleContent();
        apArticleContent.setArticleId(apArticle.getId());
        apArticleContent.setContent(wmNews.getContent());
        articleFeign.saveArticleContent(apArticleContent);
    }


    private ApArticle saveArticle(WmNews wmNews) {

        ApArticle apArticle = new ApArticle();
        apArticle.setTitle(wmNews.getTitle());
        apArticle.setLayout(wmNews.getType());
        apArticle.setFlag((byte) 0);
        apArticle.setImages(wmNews.getImages());
        apArticle.setLabels(wmNews.getLabels());
        apArticle.setCreatedTime(wmNews.getCreatedTime());
        apArticle.setPublishTime(wmNews.getPublishTime());

        //获取用户的信息
        WmUser wmUser = wemediaFeign.findWmUserById((long) wmNews.getUserId());

        if (wmUser != null && wmUser.getApUserId() != null) {
            //获取频道信息
            ApAuthor apAuthor = articleFeign.findAuthorByUserId(wmUser.getApUserId());
            apArticle.setAuthorId(apAuthor.getId().longValue());
            apArticle.setAuthorName(apAuthor.getName());

        }

        //获取频道信息
        AdChannel adChannel = adChannerMapper.selectById(wmNews.getChannelId());
        if (adChannel != null) {
            apArticle.setChannelId(adChannel.getId());
            apArticle.setChannelName(adChannel.getName());
        }
        //保存文章信息
        return articleFeign.saveArticle(apArticle);
    }

}
